/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jserver.gameserver.model.actor.instance;

import java.util.concurrent.ScheduledFuture;

import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.custom.CrystalRank;
import com.l2jserver.gameserver.custom.CustomConfig;
import com.l2jserver.gameserver.custom.HonorPointsManager;
import com.l2jserver.gameserver.custom.Message;
import com.l2jserver.gameserver.custom.MessageConfigManager;
import com.l2jserver.gameserver.custom.PcHonor;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.faction.Faction;
import com.l2jserver.gameserver.faction.FactionManager;
import com.l2jserver.gameserver.model.L2ItemInstance;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.zone.L2ZoneType;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
import com.l2jserver.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
import com.l2jserver.gameserver.network.serverpackets.ValidateLocation;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;

/**
 * @author  Laikeriz
 */

public class L2FactionCrystalInstance extends L2Npc
{
	public Faction owner = null;
	public int promile = 1000;
	public boolean _ownable = true;
	public boolean _byForce = false;
	public String name = "";
	public int crystalId = 0;
	public ScheduledFuture<?> task;
	public L2ZoneType zone = null;
	public int forbidTp = -1, owningRange = 700;
	
	public L2FactionCrystalInstance(int objectId, L2NpcTemplate template)
	{
		super(objectId, template);
		setIsInvul(true);
	}
	
	public L2FactionCrystalInstance(int objectId, L2NpcTemplate template, int ownerId, String _name, boolean ownable, boolean byForce, int _crystalId, int _owningRange, int _forbidTp)
	{
		super(objectId, template);
		
		try
		{
			name = _name;
			crystalId = _crystalId;
			if (FactionManager.getFactionById(ownerId) != null)
				owner = FactionManager.getFactionById(ownerId);
			_byForce = byForce;
			_ownable = ownable;
			if (ownable)
			{
				if (_byForce)
					setTitle((getFaction() == null ? "Nature" : getFaction().getName()));
				else
				{
					task = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new StartOwningTask(), 8000, 8000);
					setTitle((getFaction() == null ? "Nature" : getFaction().getName()) + " " + Math.round(promile / 10) + "%");
				}
			}
			setIsInvul(true);
			owningRange = _owningRange;
			forbidTp = _forbidTp;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void ownThisByForce(L2PcInstance player)
	{
		setFaction(player.getFaction());
		setTitle(owner.getName());
		updateAbnormalEffect();
		Message msg = MessageConfigManager.getMessage("crystalOwned", MessageConfigManager.currentLang);
		msg.addNextString(getName());
		msg.addNextString(getFaction().getName());
		broadcastPacket(new ExShowScreenMessage(msg.message, 5000));
		broadcastPacket(new CreatureSay(getObjectId(), 20, getName(), msg.message));
		PcHonor honor = HonorPointsManager.getInstance().getHonor(player.getObjectId());
		int amount = HonorPointsManager.getInstance().getHonorAmount("CRYSTAL");
		honor.addHonorPoints(amount);
		honor.saveHonorToDB();
		CrystalRank.increaseFactionPoint(player.getFaction(), 1);
		CustomConfig config = CustomConfig.getInstance();
		if (config.CRYSTAL_REWARD_ENABLED)
		{
			L2ItemInstance item = ItemTable.getInstance().createItem("crytal_reward", config.CRYSTAL_REWARD_ID, config.CRYSTAL_REWARD_COUNT, null);
			player.addItem("crystal_reward", item, null, true);
		}
	}
	
	public void setFaction(Faction faction)
	{
		owner = faction;
	}
	
	public Faction getFaction()
	{
		return owner;
	}
	
	@Override
	public boolean isAttackable()
	{
		return false;
	}
	
	@Override
	public boolean isAutoAttackable(L2Character attacker)
	{
		return false;
	}
	
	@Override
	public boolean doDie(L2Character killer)
	{
		return false;
	}
	
	@Override
	public void onForcedAttack(L2PcInstance player)
	{
		onAction(player);
	}
	
	@Override
	public void onAction(L2PcInstance player, boolean interact)
	{
		if (player == null || !canTarget(player))
			return;
		
		// Check if the L2PcInstance already target the L2NpcInstance
		if (this != player.getTarget())
		{
			// Set the target of the L2PcInstance player
			player.setTarget(this);
			
			// Send a Server->Client packet MyTargetSelected to the L2PcInstance player
			MyTargetSelected my = new MyTargetSelected(getObjectId(), player.getLevel() - getLevel());
			player.sendPacket(my);
			
			// Send a Server->Client packet StatusUpdate of the L2NpcInstance to the L2PcInstance to update its HP bar
			StatusUpdate su = new StatusUpdate(getObjectId());
			su.addAttribute(StatusUpdate.CUR_HP, (int) getStatus().getCurrentHp());
			su.addAttribute(StatusUpdate.MAX_HP, getMaxHp());
			player.sendPacket(su);
			
			// Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
			player.sendPacket(new ValidateLocation(this));
			rotateIfFake(player);
		}
		player.sendPacket(ActionFailed.STATIC_PACKET);
	}
	
	public void cancelOwningTask()
	{
		task.cancel(true);
	}
	
	private class StartOwningTask implements Runnable
	{
		public void run()
		{
			Faction currentFaction = getFaction();
			int currentPromile = promile;
			Message msg;
			L2PcInstance lastPlayer = null;
			for (L2Character actor : getKnownList().getKnownCharactersInRadius(owningRange))
			{
				L2PcInstance player = null;
				if (actor instanceof L2PcInstance)
					player = (L2PcInstance) actor;
				if (player != null && player.getFaction() != null && !player.getAppearance().getInvisible() && !player.isDead())
				{
					int percent = 0;
					if (player.getLevel() <= 80)
						percent += 10;
					else
						percent += 15;
					percent += promile / 100;
					
					if (getFaction() == null || getFaction() != player.getFaction())
					{
						if (promile - percent < 0)
						{
							promile = (promile - percent) * (-1);
							setFaction(player.getFaction());
							lastPlayer = player;
						}
						else
							promile -= percent;
					}
					else if (getFaction() == player.getFaction())
					{
						if (promile + percent > 1000)
							promile = 1000;
						else
							promile += percent;
					}
				}
			}
			if (promile != currentPromile)
			{
				setTitle((getFaction() == null ? "Nature" : getFaction().getName()) + " " + Math.round(promile / 10) + "%");
				updateAbnormalEffect();
				if (currentFaction != getFaction())
				{
					msg = MessageConfigManager.getMessage("crystalOwned", MessageConfigManager.currentLang);
					msg.addNextString(getName());
					msg.addNextString(getFaction().getName());
					broadcastPacket(new ExShowScreenMessage(msg.message, 5000));
					broadcastPacket(new CreatureSay(getObjectId(), 20, getName(), msg.message));
					if (lastPlayer != null)
					{
						PcHonor honor = HonorPointsManager.getInstance().getHonor(lastPlayer.getObjectId());
						int amount = HonorPointsManager.getInstance().getHonorAmount("CRYSTAL");
						honor.addHonorPoints(amount);
						honor.saveHonorToDB();
						CrystalRank.increaseFactionPoint(lastPlayer.getFaction(), 1);
						CustomConfig config = CustomConfig.getInstance();
						if (config.CRYSTAL_REWARD_ENABLED)
						{
							L2ItemInstance item = ItemTable.getInstance().createItem("crytal_reward", config.CRYSTAL_REWARD_ID, config.CRYSTAL_REWARD_COUNT, null);
							lastPlayer.addItem("crystal_reward", item, null, true);
						}
					}
				}
			}
		}
	}
}
